#IFNDEF NO_DUMMY_CLASS;
Class Dummy;
#ENDIF;

!Come spiegato negli esempi abbiamo bisogno della classe Dummy per gestire locazioni fittizie
!Se si vuole utilizzarne una diversa basta definire la costante NO_DUMMY_CLASS

#IFDEF STANDARD; !Se decidiamo di utilizzare porte standard viene compilata la classe porte con tutto il necessario
Class Porte
    with 
    x, !Si occupa di memorizzare la destinazione della porta aperta
    y, !Si occupa di memorizzare lo stato della porta (concealed o ~concealed)
    react_before[;
        if(self has open)self.x=self.door_to();else self.x=self; !Se la porta  chiusa x vale la porta stessa
        if(self has concealed)self.y=1; else self.y=0;
        ],
    has 
        door openable static female
    ;
#ENDIF;

Global n=0; Global ne=0; Global e=0; Global se=0; Global s=0; Global sw=0; 
Global w=0; Global nw=0; Global u=0; Global d=0; Global t=0;
Global dest_n=0; Global dest_ne=0; Global dest_e=0; Global dest_se=0; Global dest_s=0;
Global dest_sw=0; Global dest_w=0; Global dest_nw=0; Global dest_u=0; Global dest_d=0;

!Le 21 globali dichiarate servono alla subroutine per contare direzioni e memorizzare destinazioni

[ UscitaSub nx nex ex sex sx swx wx nwx ux dx;

!Le variabili locali vengono utilizzate nel caso si includa doors.h o easydoors.h

  nx=0; nex=0; ex=0; sex=0; sx=0; swx=0; wx=0; nwx=0; ux=0; dx=0;
  n=0;ne=0;e=0;se=0;s=0;sw=0;w=0;nw=0;u=0;d=0;t=0;
  dest_n=0;dest_ne=0;dest_e=0;dest_se=0;dest_s=0;dest_sw=0;dest_w=0;dest_nw=0;dest_u=0;dest_d=0;

!Nonostante ho inizializzato le globali a zero per sicurezza 'pulisco' tutto ogni volta

!FASE DI CALCOLO

  if(location==thedark)"^E' troppo buio per vedere le uscite.";

!In una prima stesura mi ero dimenticato di questo caso lol

  if(parent(player)~=location && parent(player)hasnt transparent && parent(player) has container)
      {print"^Ma sei dentro ",(the) parent(player),"!!^Devi uscire da l per vedere le uscite...^";rtrue;}

!Qui verifico che l'oggetto che contiene il giocatore diverso da una locazione (un armadio) abbia almeno transparent
!per poter vedere comunque le uscite disponibili
      
      #IFDEF STANDARD;  !Quanto segue vale solo per le porte standard
    
        if(location.n_to~=nothing)

!Prima di tutto ho verificato che la propriet direzionale della stanza corrisponda effettivamente a qualcosa

	  {n++;t++;dest_n=location.n_to;}

!Allora aumento le globali n (nord) e t (totale) ed assegno a dest_n (destinazione nord) il valore della propriet n_to della stanza

            if(dest_n ofclass(Porte))

!Dopodich verifico se dest_n corrisponde ad una porta; in caso positivo compio altri accertamenti

           {if(dest_n.y==1){n--;t--;}

!Prima di tutto verifico che la propriet y di dest_n (che ora vale una porta) sia uguale a 1, cio la porta ha concealed
!allora diminuisco le globali t ed n in modo che in fase di stampa vengano ignorate  

	      dest_n.react_before();

!Questa  una misura preventiva e merita un approfondimento.
!E' utile solo nel caso in cui si decida di richiamare uscitasub nella descrizione delle stanze
!Normalmente lo stato delle porte viene aggiornato ad ogni turno ma se ne attraversiamo una verr aggiornato 
!solo al turno successivo all'attraversamento
!Questo fatto (normalissimo) generava un piccolo problemino, la destinazione di una porta attraversata
!(in fase description della nuova location) corrispondeva ancora alla location in cui si era appena entrati!!!
!Quindi qui 'forzo' l'aggiornamento dello stato della porta ad ogni chiamata (attiva o passiva) alla subroutine

		dest_n=dest_n.x;}

!Fatto questo sostituisco il valore di dest_n (una porta) con il valore della sua propriet x che ora contiene il valore 'aggiornato'
!(destinazione con porta aperta, porta con porta chiusa)

        if(location.ne_to~=nothing){ne++;t++;dest_ne=location.ne_to;}
            if(dest_ne ofclass(Porte)){if(dest_ne.y==1){ne--;t--;}dest_ne.react_before();dest_ne=dest_ne.x;}
        if(location.e_to~=nothing){e++;t++;dest_e=location.e_to;}
            if(dest_e ofclass(Porte)){if(dest_e.y==1){e--;t--;}dest_e.react_before();dest_e=dest_e.x;}
        if(location.se_to~=nothing){se++;t++;dest_se=location.se_to;}
            if(dest_se ofclass(Porte)){if(dest_se.y==1){se--;t--;}dest_se.react_before();dest_se=dest_se.x;}
        if(location.s_to~=nothing){s++;t++;dest_s=location.s_to;}
            if(dest_s ofclass(Porte)){if(dest_s.y==1){s--;t--;}dest_s.react_before();dest_s=dest_s.x;}
        if(location.w_to~=nothing){w++;t++;dest_w=location.w_to;}
            if(dest_w ofclass(Porte)){if(dest_w.y==1){w--;t--;}dest_w.react_before();dest_w=dest_w.x;}
        if(location.sw_to~=nothing){sw++;t++;dest_sw=location.sw_to;}
            if(dest_sw ofclass(Porte)){if(dest_sw.y==1){sw--;t--;}dest_sw.react_before();dest_sw=dest_sw.x;}
        if(location.nw_to~=nothing){nw++;t++;dest_nw=location.nw_to;}
            if(dest_nw ofclass(Porte)){if(dest_nw.y==1){nw--;t--;}dest_nw.react_before();dest_nw=dest_nw.x;}
        if(location.u_to~=nothing){u++;t++;dest_u=location.u_to;}
            if(dest_u ofclass(Porte)){if(dest_u.y==1){u--;t--;}dest_u.react_before();dest_u=dest_u.x;}
        if(location.d_to~=nothing){d++;t++;dest_d=location.d_to;}
            if(dest_d ofclass(Porte)){if(dest_d.y==1){d--;t--;}dest_d.react_before();dest_d=dest_d.x;}

!Tutto il ragionamento di prima vale per tutte le direzioni, tranne in_to e out_to che ho escluso volutamente per via della loro
!versatilit, ma anche per non rendermi la vita troppo difficile (sempre per la loro versatilit, sarebbe diventato un lavoro immane
!verificare che fossero state abbinate a qualcosa di diverso da una delle altre...
        
      #ENDIF;
      
      #IFDEF EASYDOORS;  !Quanto segue interessa easydoors.h

        if(location.n_to~=nothing){n++;t++;dest_n=location.n_to;}

!La prima riga come sopra

            if(dest_n ofclass(Doorway))
                {if(dest_n has concealed){n--;t--;}

!Idem, appoggiandomi direttamente all'attributo concealed e NON alla propriet isconcealed che crea una describe[;rtrue;],
!lasciando ben visibile la porta (infatti  usata principalmente per eliminare 'Puoi vedere una porta qui.' 
!come specificato in easydoors.h) 

                 if(dest_n has open){
                     if(location==dest_n.side1_to())nx=dest_n.side2_to();
                     else nx=dest_n.side1_to();

!Qui se la porta  aperta abbandono react_before per aggiornarne lo stato perch, appoggiandosi a due propriet, lo stato della porta
! fisso e non deve essere aggiornato
!Per prevedere destinazioni variabili secondo condizioni assegno alla locale nx (nord x) non semplicemente side1_to (o side2_to)
!ma il suo valore di ritono (nel caso di un'eventuale embedded) quindi forzo l'esecuzione della propriet
!Fortunatamente se non c' una embedded da eseguire inform passa comunque il 'semplice' valore di ritorno

                     dest_n=nx;}

!Fatto questo assegno a dest_n il valore di nx

                }
        if(location.ne_to~=nothing){ne++;t++;dest_ne=location.ne_to;}
            if(dest_ne ofclass(Doorway))
                {if(dest_ne has concealed){ne--;t--;}
                 if(dest_ne has open){
                     if(location==dest_ne.side1_to())nex=dest_ne.side2_to();
                     else nex=dest_ne.side1_to();
                     dest_ne=nex;}
                }
        if(location.e_to~=nothing){e++;t++;dest_e=location.e_to;}
            if(dest_e ofclass(Doorway))
                {if(dest_e has concealed){e--;t--;}
                 if(dest_e has open){
                     if(location==dest_e.side1_to())ex=dest_e.side2_to();
                     else ex=dest_e.side1_to();
                     dest_e=ex;}
                }
        if(location.se_to~=nothing){se++;t++;dest_se=location.se_to;}
            if(dest_se ofclass(Doorway))
                {if(dest_se has concealed){se--;t--;}
                 if(dest_se has open){
                     if(location==dest_se.side1_to())sex=dest_se.side2_to();
                     else sex=dest_se.side1_to();
                     dest_se=sex;}
                }
        if(location.s_to~=nothing){s++;t++;dest_s=location.s_to;}
            if(dest_s ofclass(Doorway))
                {if(dest_s has concealed){s--;t--;}
                 if(dest_s has open){
                     if(location==dest_s.side1_to())sx=dest_s.side2_to();
                     else sx=dest_s.side1_to();
                     dest_s=sx;}
                }
        if(location.sw_to~=nothing){sw++;t++;dest_sw=location.sw_to;}
            if(dest_sw ofclass(Doorway))
                {if(dest_sw has concealed){sw--;t--;}
                 if(dest_sw has open){
                     if(location==dest_sw.side1_to())swx=dest_sw.side2_to();
                     else swx=dest_sw.side1_to();
                     dest_sw=swx;}
                }
        if(location.w_to~=nothing){w++;t++;dest_w=location.w_to;}
            if(dest_w ofclass(Doorway))
                {if(dest_w has concealed){w--;t--;}
                 if(dest_w has open){
                     if(location==dest_w.side1_to())wx=dest_w.side2_to();
                     else wx=dest_w.side1_to();
                     dest_w=wx;}
                }
        if(location.nw_to~=nothing){nw++;t++;dest_nw=location.nw_to;}
            if(dest_nw ofclass(Doorway))
                {if(dest_nw has concealed){nw--;t--;}
                 if(dest_nw has open){
                     if(location==dest_nw.side1_to())nwx=dest_nw.side2_to();
                     else nwx=dest_nw.side1_to();
                     dest_nw=nwx;}
                }
        if(location.u_to~=nothing){u++;t++;dest_u=location.u_to;}
            if(dest_u ofclass(Doorway))
                {if(dest_u has concealed){u--;t--;}
                 if(dest_u has open){
                     if(location==dest_u.side1_to())ux=dest_u.side2_to();
                     else ux=dest_u.side1_to();
                     dest_u=ux;}
                }
        if(location.d_to~=nothing){d++;t++;dest_d=location.d_to;}
            if(dest_d ofclass(Doorway))
                {if(dest_d has concealed){d--;t--;}
                 if(dest_d has open){
                     if(location==dest_d.side1_to())dx=dest_d.side2_to();
                     else dx=dest_d.side1_to();
                     dest_d=dx;}
                }

!Come sopra trane in_to e out_to (sempre come sopra)

      #ENDIF;
      
      #IFDEF DOORS;   !Quanto segue interessa doors.h

        if(location.n_to~=nothing){n++;t++;dest_n=location.n_to;}

!La prima riga ormai  standard

            if(dest_n ofclass(Connector))
                {if(dest_n has concealed){n--;t--;}

!Come per easydoors mi appoggio direttamente a concealed e non ad un valore derivato

                 if(dest_n has open)dest_n=dest_n.n_to();

!Essendo Connector 'equiparata' ad un oggetto standard  sufficiente memorizzare in dest_n il valore di ritorno della propriet
!n_to del Connector che per NON pu essere una embedded perch avrebbe come valore di ritorno l'embedded stessa e NON il valore di ritono
!della embedded; forse a causa del sistema di gestione tramite objectloop, forse dipende dal fatto che non si 'sosta' all'interno del 
!Connector, non ne sono ancora sicuro
!Si pu ovviare alla cosa dichiarando l'n_to del connector come propriet 'vuota' (n_to ,) facendo eseguire l'embedded che le assegna un 
!valore nella react_before del Connector stesso
!In questo caso la react_before non deve essere forzata nella subroutine perch le destinazioni 'all'indietro' del Connector sono
!memorizzate in linea di massima nella propriet direzionale contraria che, quindi, viene gi verificata successivamente dalla subroutine

                 }
        if(location.ne_to~=nothing){ne++;t++;dest_ne=location.ne_to;}
            if(dest_ne ofclass(Connector))
                {if(dest_ne has concealed){ne--;t--;}
                 if(dest_ne has open)dest_ne=dest_ne.ne_to();
                 }
        if(location.e_to~=nothing){e++;t++;dest_e=location.e_to;}
            if(dest_e ofclass(Connector))
                {if(dest_e has concealed){e--;t--;}
                 if(dest_e has open)dest_e=dest_e.e_to();
                 }
        if(location.se_to~=nothing){se++;t++;dest_se=location.se_to;}
            if(dest_se ofclass(Connector))
                {if(dest_se has concealed){se--;t--;}
                 if(dest_se has open)dest_se=dest_se.se_to();
                 }
        if(location.s_to~=nothing){s++;t++;dest_s=location.s_to;}
            if(dest_s ofclass(Connector))
                {if(dest_s has concealed){s--;t--;}
                 if(dest_s has open)dest_s=dest_s.s_to();
                 }
        if(location.sw_to~=nothing){sw++;t++;dest_sw=location.sw_to;}
            if(dest_sw ofclass(Connector))
                {if(dest_sw has concealed){sw--;t--;}
                 if(dest_sw has open)dest_sw=dest_sw.sw_to();
                 }
        if(location.w_to~=nothing){w++;t++;dest_w=location.w_to;}
            if(dest_w ofclass(Connector))
                {if(dest_w has concealed){w--;t--;}
                 if(dest_w has open)dest_w=dest_w.w_to();
                 }
        if(location.nw_to~=nothing){nw++;t++;dest_nw=location.nw_to;}
            if(dest_nw ofclass(Connector))
                {if(dest_nw has concealed){nw--;t--;}
                 if(dest_nw has open)dest_nw=dest_nw.nw_to();
                 }
        if(location.u_to~=nothing){u++;t++;dest_u=location.u_to;}
            if(dest_u ofclass(Connector))
                {if(dest_u has concealed){u--;t--;}
                 if(dest_u has open)dest_u=dest_u.u_to();
                 }
        if(location.d_to~=nothing){d++;t++;dest_d=location.d_to;}
            if(dest_d ofclass(Connector))
                {if(dest_d has concealed){d--;t--;}
                 if(dest_d has open)dest_d=dest_d.d_to();
                 }

!Come sopra

      #ENDIF;

!FASE DI STAMPA
      
        if(t==0)print"^Spiacente, non ci sono uscite.^";

!A questo punto se la globale t vale ancora zero uscitasub non ha rilevato uscite

        if(t==1)
            {print"^Puoi andare solo ";
                if(n==1)print"a nord verso ",(the)dest_n,".^";
                if(ne==1)print"a nordest verso ",(the)dest_ne,".^";
                if(e==1)print"ad est verso ",(the)dest_e,".^";
                if(se==1)print"a sudest verso ",(the)dest_se,".^";
                if(s==1)print"a sud verso ",(the)dest_s,".^";
                if(sw==1)print"a sodovest verso ",(the)dest_sw,".^";
                if(w==1)print"ad ovest verso ",(the)dest_w,".^";
                if(nw==1)print"a nordovest verso ",(the)dest_nw,".^";
                if(u==1)print"su verso ",(the)dest_u,".^";
                if(d==1)print"gi verso ",(the)dest_d,".^";
            }

!Il caso pi semplice  quando c' una sola uscita

        if(t>1)
            {print"^Le uscite possibili sono: ";
                if(n==1)print"a nord verso ",(the)dest_n,", ";
                if(ne==1){print"a nordest verso ",(the)dest_ne;
                          if(e==1||se==1||s==1||sw==1||w==1||nw==1||u==1||d==1)print", ";
                          else print".^";
                          }
                if(e==1){print"ad est verso ",(the)dest_e;
                         if(se==1||s==1||sw==1||w==1||nw==1||u==1||d==1)print", ";
                         else print".^";
                         }
                if(se==1){print"a sudest verso ",(the)dest_se;
                          if(s==1||sw==1||w==1||nw==1||u==1||d==1)print", ";
                          else print".^";
                          }
                if(s==1){print"a sud verso ",(the)dest_s;
                         if(sw==1||w==1||u==1||d==1)print", ";
                         else print".^";
                         }
                if(sw==1){print"a sudovest verso ",(the)dest_sw;
                          if(w==1||nw==1||u==1||d==1)print", ";
                          else print".^";
                          }
                if(w==1){print"ad ovest verso ",(the)dest_w;
                         if(nw==1||u==1||d==1)print", ";
                         else print".^";
                         }
                if(nw==1){print"a nordovest verso ",(the)dest_nw;
                         if(u==1||d==1)print", ";
                         else print".^";
                         }
                if(u==1){print"su verso ",(the)dest_u;
                         if(d==1)print", ";
                         else print".^";
                         }
                if(d==1)print"gi verso ",(the)dest_d,".^";
            }

!Nel caso ci siano pi uscite, verificate in senso orario a partire da nord, faccio stampare una virgola se almeno una delle globali
!'direzionali' successive vale uno; diversamente stampo un punto

    if (AfterRoutines());return;

!Viste tutti i valori verificati, memorizzati, sostituiti l'if(Afterroutines()) mi sembra indispensabile

    ];
  
Verb 'uscita' 'uscite' 'direzioni' 'ux' *   -> Uscita;

!Il tocco finale ^_^
